package server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.SocketException;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

public class ClientDispatcher extends Thread {

	private FileServer fs;
	private boolean listening;

	private List<ClientWorker> workers;

	private ServerSocket serverSocket;

	public ClientDispatcher(FileServer fs) {
		this.fs = fs;
		workers = Collections.synchronizedList(new Vector<ClientWorker>());

		try {
			serverSocket = new ServerSocket(this.fs.getTcpPort());
		} catch (IOException e) {
			System.out.println("Error: An unexpected error occurred!");
		}
	}

	public void shutdown() {

		listening = false;

		for (ClientWorker worker : workers){
			try {
				worker.join();
			} catch (InterruptedException e) {
				//ignore
			}
		}
		try {

			if (serverSocket != null && !serverSocket.isClosed())
				serverSocket.close();

			serverSocket = null;

		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Error: An unexpected error occurred!");
		}
	}

	@Override
	public void run() {
		try {
			listening = true;

			ClientWorker worker;

			while (listening) {

				worker = new ClientWorker(this.serverSocket.accept(), fs);
				worker.start();

				workers.add(worker);

				// garbage collector for dead threads
				// for (int i = 0; i < pWorkers.size(); i++) {
				// if (!pWorkers.get(i).isAlive())
				// pWorkers.remove(i);
				// }
			}

		} catch (SocketException e) {
			// Gets thrown on shutdown so -> Ignore
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Error: An unexpected error occurred!");
		}
	}
}
